package com.example.myblog_springboot.controller;

import com.example.myblog_springboot.service.MyblogUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.time.LocalTime;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

@Controller
@RequestMapping("/v1/datasets/")
@Tag(name = "用户管理接口")
@CrossOrigin(origins = "*")
public class MyblogUserController_copy {
    private static final int PEAK_PERMITS = 5;
    // 信号量：高峰期并发控制（2个许可，公平模式）
    private Semaphore semaphore = new Semaphore(PEAK_PERMITS, true);

    // 非高峰期频率控制参数（常量定义更清晰）
    private static final int NON_PEAK_MAX_CALLS = 8; // 每分钟最大调用次数
    private static final long MINUTE_MILLIS = 60 * 1000; // 一分钟毫秒数（重命名更直观）

    // 线程安全的计数器和时间戳（增加注释说明用途）
    private static AtomicInteger nonPeakCallCount = new AtomicInteger(0); // 非高峰期累计调用次数
    private static AtomicLong currentMinute = new AtomicLong(0); // 当前分钟的时间戳（用于计数重置）

    @Autowired
    private MyblogUserService myblogUserService;

    // 补充路径参数接收（原代码遗漏了{datasetId}的处理）
    @RequestMapping(value = "/{datasetId}/retrieve", method = RequestMethod.POST)
    @Operation(summary = "获取用户信息列表")
    @ResponseBody
    public Map<String, Object> getUser() {

        HashMap<String, Object> resultMap = new HashMap<>();
        String data = null;
        String message = "success";
        int code = 200; // 统一定义状态码

        try {
            // 1. 判断是否为非高峰期
            if (isNonPeakTime()) {
                // 2. 非高峰期：检查频率限制
                if (canCallInNonPeak()) {
                    data = myblogUserService.getString();
                    message = "接口调用成功（非高峰期）";
                } else {
                    message = "接口调用失败：非高峰期超出每分钟8次限制";
                }
            } else {
                // 3. 高峰期：检查并发限制
                if (semaphore.tryAcquire()) { // 尝试获取许可（无超时，原逻辑保持不变）
                    try {
                        data = myblogUserService.getString();
                        message = "接口调用成功（高峰期）";
                        // 模拟接口处理时间
                        TimeUnit.SECONDS.sleep(1);
                    } finally {
                        semaphore.release(); // 确保释放许可，避免死锁
                    }
                } else {
                    message = "接口调用失败：高峰期超出"+PEAK_PERMITS+"个并发限制";
                }
            }

        } catch (Exception e) {
            // 异常处理：返回错误信息（避免直接抛异常给前端）
            message = "接口调用异常：" + e.getMessage();
            code = 500; // 异常状态码
            e.printStackTrace(); // 打印异常堆栈，方便排查
        }

        // 统一设置返回结果（避免重复put操作）
        resultMap.put("data", data);
        resultMap.put("msg", message);
        resultMap.put("code", code);
        return resultMap;
    }

    /**
     * 判断当前是否为非业务高峰期（20:00-次日08:00）
     */
    private static boolean isNonPeakTime() {
        int currentHour = LocalTime.now().getHour(); // 使用LocalTime替代旧API，更清晰
        // 非高峰期：20点及以后 或 8点以前
//        20~24
//        0~8
        return currentHour >= 18 || currentHour < 8;
    }

    /**
     * 非高峰期调用校验：每分钟不超过8次
     */
    private static boolean canCallInNonPeak() {
        long now = System.currentTimeMillis();
        long minuteTimestamp = now / MINUTE_MILLIS; // 当前分钟的时间戳

        // 跨分钟时重置计数器（原子操作保证线程安全）
        if (currentMinute.get() != minuteTimestamp) {
            currentMinute.compareAndSet(currentMinute.get(), minuteTimestamp);
            nonPeakCallCount.set(0);
        }

        // 检查调用次数是否超限
        return nonPeakCallCount.incrementAndGet() <= NON_PEAK_MAX_CALLS;
    }
}